#region Using Directives

using System;
using System.Collections.Generic;
using System.Reflection;
using System.ComponentModel;
using System.Web.UI.WebControls;

#endregion

namespace Web
{
    public static class EnumHelper
    {
        #region Enum To List

        public static List<T> EnumToList<T>()
        {
            Type enumType = typeof(T);

            // Can't use type constraints on value types, so have to do check like this
            if (enumType.BaseType != typeof(Enum))
                throw new ArgumentException("T must be of type System.Enum");

            Array enumValArray = Enum.GetValues(enumType);
            List<T> enumValList = new List<T>(enumValArray.Length);

            foreach (int val in enumValArray)
            {
                enumValList.Add((T)Enum.Parse(enumType, val.ToString()));
            }

            return enumValList;
        }

        #endregion

        #region Enum Descriptions

        /// <summary>
        /// Reads the description value from an enumeration.
        /// </summary>
        /// <param name="value">The description of the enum value to read.</param>
        /// <returns>Returns the description string or the enum value 
        /// as a string, if no description was found.</returns>
        /// <seealso cref="http://www.codeproject.com/csharp/EnumDescConverter.asp."/>
        public static string GetEnumDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());

            DescriptionAttribute[] attributes =
                (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute),
                false);

            if (attributes != null &&
                attributes.Length > 0)
            {
                return attributes[0].Description;
            }
            else
            {
                return value.ToString();
            }
        }

        /// <summary>
        /// Gets a list of all the description values for a given enum
        /// </summary>
        /// <typeparam name="T">The enum type you want the descriptions for</typeparam>
        /// <returns></returns>
        public static List<string> GetEnumDescriptions<T>() where T : struct
        {
            List<string> values = new List<string>();
            foreach (int i in Enum.GetValues(typeof(T)))
            {
                System.Enum item = (System.Enum)Enum.ToObject(typeof(T), i);
                values.Add(GetEnumDescription(item));
            }
            return values;
        }

        #endregion

        public static T Parse<T>(string value)
        {
            return (T)Enum.Parse(typeof(T), value, true);
        }
    }
}